#include "config.h"
#include "usart.h"
#include "gpio.h"
#include "JA_Protocol.h"
#include "user_usart.h"
#include "malloc.h"
#include "Model_Info.h"
extern Mallco_dev mallco_dev; //内存管理器
JA_Protocol_TCB ja_tcb; // JA 协议控制块
#define JA_Protocol_MAX_SIZE 100
uint8_t JA_Protocol_BUF[JA_Protocol_MAX_SIZE]; // JA 协议缓存

/// @brief 获取RS485 默认配置参数
/// @return 
UartPortConfig_t GetDefaultRS485Config(void)
{
	UartPortConfig_t rs_485;
	rs_485.BandRate=9600;
	rs_485.Data_Size=ZY_UART_DataBits_8BIT;
	rs_485.Parity=ZY_UART_PARITY_NONE;
	rs_485.StopBits=ZY_UART_StopBits_1;
	return rs_485;
}

/// @brief 获取RF 默认参数
/// @param  
/// @return 
Lora_RFConfig_t GetDefaultRFConfig(void)
{
	Lora_RFConfig_t lora_config;
	lora_config.RF_power=22;
	lora_config.RF_RXFrequency=450000000;
	lora_config.RF_TXFrequency=450000000;
	lora_config.ErrorCoding=LoRa_ErrorCoding_4_5;
	lora_config.SignalBw=LoRa_SignalBw_125K;
	lora_config.SpreadingFactor=LoRa_SpreadingFactor_512;
	return lora_config;
}
/// @brief 获取 lora 网络配置参数
/// @param  
/// @return 
Lora_NetWorkConfig_t GetDefaultNetWorkConfig(void)
{
	Lora_NetWorkConfig_t lora_net;
	lora_net.add=1;
	lora_net.id=1;
	lora_net.enable.ADDR=0;
	lora_net.enable.Encryption=0;
	lora_net.enable.Relay=0;
	return lora_net;
}

/// @brief 设置无线配置参数
/// @param  rf 配置
/// @return 
void Set_RFConfig(Lora_RFConfig_t rf)
{
	model_info_handle.model_info.rf_config=rf;
}
/// @brief 设置网络 配置参数
/// @param  net 配置
/// @return 
void Set_NetWorkConfig(Lora_NetWorkConfig_t net)
{
	model_info_handle.model_info.net_config=net;
}

/// @brief 设置端口 配置参数
/// @param  net 配置
/// @return 
void Set_PortConfig(UartPortConfig_t rs232,UartPortConfig_t rs485)
{
	model_info_handle.model_info.rs485=rs485;
}
/// @brief 保存配置参数
/// @param  net 配置
/// @return 
void Save_Config(void)
{
	Clear_Info();
	Save_ConfigInfo(&model_info_handle.general_info);
	//Save_ModelConfigInfo(&model_info_handle.model_info);
}

void Set_Info(uint32_t id)
{
	model_info_handle.general_info.SN=id;
}

/// @brief 配置回调函数
/// @param data 数据
/// @param Size 数据长度
void Config_RxCallback(uint8_t *data, uint8_t Size)
{
	JA_BytesArray reply_buf;
	JA_StatusTypeDef res;
	for(uint8_t i=0;i<Size;i++)
	{
		res = JA_Decode(&ja_tcb, data[i], &reply_buf);
		if (res == JA_Decode_OK)
		{
			if (reply_buf.len)
			{
				UART1SendData(reply_buf.bytes, reply_buf.len);
				myfree(&mallco_dev, reply_buf.bytes);
			}
		}
	}
}


/// @brief 获取拨码开关配置运行模式
/// @return 运行模式
uint8_t GetConfigModel()
{
	uint8_t model_status=0;
	return (model_status&0x03);
}

/// @brief RS485 初始化模块配置
/// @param config 配置参数
void InitModel_RS485(UartPortConfig_t config)
{
	uint32_t wordlength=UART_WORDLENGTH_8B;
	uint32_t Parity=UART_PARITY_NONE;
	uint32_t StopBits=UART_STOPBITS_1;
	//数据长度
	if(config.Data_Size==ZY_UART_DataBits_7BIT)
	{
		wordlength=UART_WORDLENGTH_7B;
	}
	else if(config.Data_Size==ZY_UART_DataBits_8BIT)
	{
		wordlength=UART_WORDLENGTH_8B;
	}
	else if(config.Data_Size==ZY_UART_DataBits_9BIT)
	{
		wordlength=UART_WORDLENGTH_9B;
	}
	//校验位
	if(config.Parity==ZY_UART_PARITY_NONE)
	{
		Parity=UART_PARITY_NONE;
	}
	else if(config.Parity==ZY_UART_RARITY_EVEN)
	{
		Parity=UART_PARITY_EVEN;
	}
	else if(config.Parity==ZY_UART_RARITY_ODD)
	{
		Parity=UART_PARITY_ODD;
	}
	//停止位
	if(config.StopBits==ZY_UART_StopBits_1)
	{
		StopBits=UART_STOPBITS_1;
	}
	else if(config.StopBits==ZY_UART_StopBits_1_5)
	{
		StopBits=UART_STOPBITS_1_5;
	}
	else if(config.StopBits==ZY_UART_StopBits_2)
	{
		StopBits=UART_STOPBITS_2;
	}
	else if(config.StopBits==ZY_UART_StopBits_0_5)
	{
		StopBits=UART_STOPBITS_0_5;
	}
	
  huart1.Instance = USART1;
  huart1.Init.BaudRate = config.BandRate;
  huart1.Init.WordLength = wordlength;
  huart1.Init.StopBits = StopBits;
  huart1.Init.Parity = Parity;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart1.Init.ClockPrescaler = UART_PRESCALER_DIV1;
  huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_RS485Ex_Init(&huart1, UART_DE_POLARITY_HIGH, 0, 0) != HAL_OK)
  {
    Error_Handler();
  }
}

/// @brief DTU初始化
/// @param  
void Init_Model(void)
{
	UartPortConfig_t rs_485;
	UartPortConfig_t rs_232;
	Init_Modelinfo();
	model_info_handle.run_model=GetConfigModel();   //运行模式
	if(model_info_handle.run_model==RUNModel_CONFIG)
	{
    JA_Create(&ja_tcb, DTU_Config_Parse, JA_Protocol_BUF, JA_Protocol_MAX_SIZE);
		rs_485.BandRate=9600;
		rs_485.Data_Size=8;
		rs_485.Parity=ZY_UART_PARITY_NONE;
		rs_485.StopBits=ZY_UART_StopBits_1;
		rs_232=rs_485;
	}
	else
	{
		rs_485=model_info_handle.model_info.rs485;
	}
	InitModel_RS485(rs_485);
}


/// @brief 协议回复数据
/// @param protocol 协议
/// @return 回复的数据
JA_BytesArray Reply_Data(JA_Protocol protocol)
{
	JA_BytesArray buf;
	buf.bytes = mymalloc(&mallco_dev, protocol.data.data_len + 8);
	if (buf.bytes)
	{
		buf.len = JA_Package(protocol, buf.bytes);
		return buf;
	}
}

/// @brief 回复状态
/// @param protocol 协议 
/// @param status 状态
/// @return 
JA_BytesArray Reply_status(JA_Protocol protocol,uint8_t status)
{
	JA_Protocol r_protocol;
	r_protocol.Address=protocol.Address;
	r_protocol.CS_Vsersion=protocol.CS_Vsersion;
	r_protocol.SN=protocol.SN;
	r_protocol.data.Opcode=protocol.data.Opcode;
	r_protocol.data.data=&status;
	r_protocol.data.data_len=1;
	return Reply_Data(r_protocol);
}


/// @brief 查询信息命令解析
/// @param protocol 协议
/// @return 查询参数
JA_BytesArray Get_Info_Parse(JA_Protocol protocol)
{
	JA_Protocol r_protocol;
	Command_info_t info;
	info.software_version.major=APP_VERSION_Major;
	info.software_version.minor=App_VERSION_Minor;
	info.software_version.revision=APP_VERSION_Revision;
	info.software_version.build=APP_VERSION_Build;
	info.solidify=model_info_handle.general_info;
	info.dev_type=model_info_handle.model_type;
	//mymemcpy((uint8_t*)&r_protocol.data.data,&info,sizeof(Command_info_t));
	r_protocol.data.data=(uint8_t *)&info;
	r_protocol.Address=protocol.Address;
	r_protocol.CS_Vsersion=protocol.CS_Vsersion;
	r_protocol.SN=protocol.SN;
	r_protocol.data.Opcode=protocol.data.Opcode;
	r_protocol.data.data_len=sizeof(Command_info_t);
	return Reply_Data(r_protocol);
}

/// @brief 查询无线配置参数解析
/// @param protocol 协议
/// @return 查询参数
JA_BytesArray Get_RFInfo_Parse(JA_Protocol protocol)
{
	JA_Protocol r_protocol;
	Command_RF_INFO_t info;
	info.rf=model_info_handle.model_info.rf_config;
	//mymemcpy((uint8_t*)&r_protocol.data.data,&info,sizeof(Command_info_t));
	r_protocol.data.data=(uint8_t *)&info;
	r_protocol.Address=protocol.Address;
	r_protocol.CS_Vsersion=protocol.CS_Vsersion;
	r_protocol.SN=protocol.SN;
	r_protocol.data.Opcode=protocol.data.Opcode;
	r_protocol.data.data_len=sizeof(Command_RF_INFO_t);
	return Reply_Data(r_protocol);
}
/// @brief 查询网络参数解析
/// @param protocol 协议
/// @return 查询参数
JA_BytesArray Get_NetInfo_Parse(JA_Protocol protocol)
{
	JA_Protocol r_protocol;
	Command_NetWork_INFO_t info;
	info.net_work=model_info_handle.model_info.net_config;
	r_protocol.data.data=(uint8_t *)&info;
	r_protocol.Address=protocol.Address;
	r_protocol.CS_Vsersion=protocol.CS_Vsersion;
	r_protocol.SN=protocol.SN;
	r_protocol.data.Opcode=protocol.data.Opcode;
	r_protocol.data.data_len=sizeof(Command_NetWork_INFO_t);
	return Reply_Data(r_protocol);
}
/// @brief 查询端口参数解析
/// @param protocol 协议
/// @return 查询参数
JA_BytesArray Get_Port_Parse(JA_Protocol protocol)
{
	JA_Protocol r_protocol;
	Command_PortInfo_t info;
	info.rs485_port=model_info_handle.model_info.rs485;
	r_protocol.data.data=(uint8_t *)&info;
	r_protocol.Address=protocol.Address;
	r_protocol.CS_Vsersion=protocol.CS_Vsersion;
	r_protocol.SN=protocol.SN;
	r_protocol.data.Opcode=protocol.data.Opcode;
	r_protocol.data.data_len=sizeof(Command_PortInfo_t);
	return Reply_Data(r_protocol);
}
/// @brief 设置无线参数解析
/// @param protocol 协议
/// @return 查询参数
JA_BytesArray Set_RF_Parse(JA_Protocol protocol)
{
	JA_Protocol r_protocol;
	Command_RF_INFO_t rf_info;
	
	mymemcpy((uint8_t*)&rf_info,protocol.data.data,sizeof(Command_RF_INFO_t));
	Set_RFConfig(rf_info.rf);
	r_protocol.Address=protocol.Address;
	r_protocol.CS_Vsersion=protocol.CS_Vsersion;
	r_protocol.SN=protocol.SN;
	r_protocol.data.Opcode=protocol.data.Opcode;
	return Reply_status(r_protocol,1);
}

/// @brief 设置网络参数解析
/// @param protocol 协议
/// @return 查询参数
JA_BytesArray Set_NetWork_Parse(JA_Protocol protocol)
{
	JA_Protocol r_protocol;
	Command_NetWork_INFO_t net_info;
	mymemcpy((uint8_t*)&net_info,protocol.data.data,sizeof(Command_NetWork_INFO_t));
	Set_NetWorkConfig(net_info.net_work);
	r_protocol.Address=protocol.Address;
	r_protocol.CS_Vsersion=protocol.CS_Vsersion;
	r_protocol.SN=protocol.SN;
	r_protocol.data.Opcode=protocol.data.Opcode;
	return Reply_status(r_protocol,1);
}

/// @brief 设置端口参数解析
/// @param protocol 协议
/// @return 查询参数
JA_BytesArray Set_Port_Parse(JA_Protocol protocol)
{
	JA_Protocol r_protocol;
	Command_PortInfo_t port_info;
	mymemcpy((uint8_t*)&port_info,protocol.data.data,sizeof(Command_PortInfo_t));
	Set_PortConfig(port_info.rs232_port,port_info.rs485_port);
	r_protocol.Address=protocol.Address;
	r_protocol.CS_Vsersion=protocol.CS_Vsersion;
	r_protocol.SN=protocol.SN;
	r_protocol.data.Opcode=protocol.data.Opcode;
	return Reply_status(r_protocol,1);
}
//设置出厂信息
JA_BytesArray Set_Info_Parse(JA_Protocol protocol)
{
	JA_Protocol r_protocol;
	Command_SetInfo_t info;
	mymemcpy((uint8_t*)&info,protocol.data.data,sizeof(Command_SetInfo_t));
	Set_Info(info.id);
	//Set_PortConfig(port_info.rs232_port,port_info.rs485_port);
	r_protocol.Address=protocol.Address;
	r_protocol.CS_Vsersion=protocol.CS_Vsersion;
	r_protocol.SN=protocol.SN;
	r_protocol.data.Opcode=protocol.data.Opcode;
	return Reply_status(r_protocol,1);
}
/// @brief 保存参数解析
/// @param protocol 协议
/// @return 保存状态
JA_BytesArray Save_Parse(JA_Protocol protocol)
{
	JA_Protocol r_protocol;
	Command_PortInfo_t port_info;
	Save_Config();
	r_protocol.Address=protocol.Address;
	r_protocol.CS_Vsersion=protocol.CS_Vsersion;
	r_protocol.SN=protocol.SN;
	r_protocol.data.Opcode=protocol.data.Opcode;
	return Reply_status(r_protocol,1);
}

/// @brief 进入IAP
/// @param protocol 协议
/// @return 回复数据
JA_BytesArray IAP_Enter_Parse(JA_Protocol protocol)
{
	JA_Protocol r_protocol;
	r_protocol.Address=protocol.Address;
	model_info_handle.iap_info.ipa_step=IAP_STEP_IAP;
	Save_IAPConfig(&model_info_handle.iap_info);
	NVIC_SystemReset();
	//Start_IAP_Update(&iap_update_tcb);
	r_protocol.CS_Vsersion=protocol.CS_Vsersion;
	r_protocol.SN=protocol.SN;
	r_protocol.data.Opcode=protocol.data.Opcode;
	return Reply_status(r_protocol,0);
}
/// @brief DTU 配置协议解析
/// @param protocol 协议
/// @param command_buf 命令buf
/// @return 协议回复
JA_BytesArray  DTU_Config_Parse(JA_Protocol protocol, uint8_t *command_buf)
{
	JA_BytesArray reply_buf;
	reply_buf.len = 0;
	reply_buf.bytes = NULL;
	
	switch (protocol.data.Opcode)
	{
	case (uint8_t)ConfigCommand_SaveConfig:       //保存配置参数
		reply_buf=Save_Parse(protocol);
		break;	
	case (uint8_t)ConfigCommand_GetInfo:          //查询固化信息
		reply_buf=Get_Info_Parse(protocol);
		break;
	case (uint8_t)ConfigCommand_GetRFCONFIG:      //查询无线配置信息
		reply_buf=Get_RFInfo_Parse(protocol);
		break;
	case  (uint8_t)ConfigCommand_GetNetCONFIG:    //查询网络配置信息
		reply_buf=Get_NetInfo_Parse(protocol);                                        
		break;
	case  (uint8_t)ConfigCommand_GetPortCONFIG:   //获取端口配置信息
		reply_buf=Get_Port_Parse(protocol);
		break;   
	case  (uint8_t)ConfigCommand_SetRFCONFIG:     //设置射频信息
		reply_buf=Set_RF_Parse(protocol);
		break;
	case  (uint8_t)ConfigCommand_SetNetCONFIG:    //设置网络配置信息
		reply_buf=Set_NetWork_Parse(protocol);
		break;
	case  (uint8_t)ConfigCommand_SetPortCONFIG:   //设置端口配置信息
		reply_buf=Set_Port_Parse(protocol);         //
		break;
	case (uint8_t)IAP_Enter:
		//reply_buf=IAP_Enter_Parse(protocol);        //进入IAP
	  break;
	case (uint8_t)ConfigCommand_SetInfo:         //设置出厂信息
		reply_buf=Set_Info_Parse(protocol);
	  break;
	default:
		break;
	}
	return reply_buf;
}
